package com.rengwuxian.coursecoroutines._1_basics

import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.View
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import com.rengwuxian.coursecoroutines.ui.theme.CourseCoroutinesTheme
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.launch
import kotlinx.coroutines.newFixedThreadPoolContext
import kotlinx.coroutines.newSingleThreadContext
import java.util.concurrent.Executors
import kotlin.concurrent.thread
import kotlin.coroutines.EmptyCoroutineContext
/**
 * 切线程：launch()
 * CoroutineScope、launch()、ContinuationInterceptor、CoroutineDispatcher
 *
 * 对于JVM上面的Kotlin来说：协程就是一个用线程来实现的并发管理库。
 *
 * 并发管理的内容很多很杂：
 * 个人总结分为三类：
 * 1.切线程(不想卡住当前线程)
 * 2.各个线程执行过程中等待别的线程（线程之间在流程上的配合）
 * 3.互斥锁（线程之间共享资源的保护，就是所谓的线程安全）
 *
 * 传统切线程：
 * 1.直接thread
 * 2.线程池
 * 3.handler main looper，然后post（切到主线程）
 *
 * kotlin协程的引用，需要加入这两个库
 * implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1"
 * implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1"
 * gradle版本管理的依赖：可以使用toml的格式
 *
 * 协程的创建：类似与线程池
 * CoroutineScope的功能不止是线程池的管理，还有更多上下文的信息
 * 把代码装起来，丢入线程/线程池去运行。
 *
 *
 * 在协程中「管理任务执行」的线程的工具 ： ContinuationInterceptor
 * 其唯一的子类：CoroutineDispatcher：协程调度器
 * 在Dispatchers中可以看到有四类CoroutineDispatcher：
 * 1. Default：默认的调度器，一般是CPU计算密集型的任务（全局的线程池来处理任务）
 *             线程数和CPU核心数绑定，这样可以达到最高的效率
 * 2. IO：IO密集型的任务，一般是网络请求，文件读写等（全局的线程池来处理任务）
 *        input/output 是只跟内存之外的世界进行交互的内容。一般是指设备的磁盘读写，网络请求
 *        工作期间：CPU是闲置的。
 *        正常情况下是64个线程。更充分利用CPU的效率
 *        IO/Default 内部实现唯一区别就是线程数不同
 * 3. Main：协程的代码块会执行在主线程中（UI线程）
 * 4. Unconfined：不确定的调度器，会在当前线程中直接执行，
 *                不仅在启动协程的时候不会切线程，挂起函数执行完后，也不会把线程切回去（不推荐使用，结果难以预期）
 *
 * 5.自定义协程的线程池：(Delicate的API)
 *     val context = newFixedThreadPoolContext(4, "MyThreadPool")
 *     val context1 = newSingleThreadContext("MySingleThread") // 实验性的
 *     val scope1 = CoroutineScope(context)
 *     context.close()
 */
class LaunchCoroutineActivity : ComponentActivity() {

  @OptIn(DelicateCoroutinesApi::class, ExperimentalCoroutinesApi::class)
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    enableEdgeToEdge()
    setContent {
      CourseCoroutinesTheme {}
    }

    thread {

    }

    println("Main thread: ${Thread.currentThread().name}")
    val executor = Executors.newCachedThreadPool()
    executor.execute {
      println("Executor thread: ${Thread.currentThread().name}")
    }

    val context = newFixedThreadPoolContext(20, "MyThread")
    val context1 = newSingleThreadContext("MyThread")
    val scope = CoroutineScope(context)
    context.close()
    scope.launch {
      println("Coroutine thread: ${Thread.currentThread().name}")
    }
    scope.launch {
      println("Coroutine thread: ${Thread.currentThread().name}")
    }

    // I/O: input / output 100k

  }
}